<template>
  <div :class="prefixCls">
    <Popover
      title=""
      trigger="click"
      @open-change="handlePopoverVisibleChange"
      :overlayClassName="`${prefixCls}__overlay`"
    >
      <Badge :count="getCount" :dot="true">
        <BellOutlined :class="noticeAnimation && 'notice-icon-animation'" />
      </Badge>
      <template #content>
        <Tabs tab-position="top" size="small" centered v-model:activeKey="activeTab">
          <TabPane :key="1">
            <template #tab>
              {{ t('layout.header.notify.message') }}
            </template>

            <AdList @register="registerMsgList" @fetch-success="handleMsgFetchSuccess">
              <template #avatar="{ item }">
                <ImageBox :width="30" :height="30" :src="item.Icon" :fallback="infoImage" />
              </template>
              <template #title="{ item }">
                <a style="font-size: 16px" @click="handleMsgPreview(item)">
                  {{ item.Title }}
                </a>
              </template>
              <template #description="{ item }">
                <div>
                  <div class="description" v-if="item.Content">
                    {{ item.Content }}
                  </div>
                  <span style="font-size: 12px">{{
                    formatToDate(item.SendTime, 'YYYY-MM-DD HH:mm')
                  }}</span>
                </div>
              </template>
            </AdList>
          </TabPane>
          <TabPane :key="2">
            <template #tab>
              {{ t('layout.header.notify.task') }}
              <!-- <span v-if="item.list.length !== 0">({{ item.list.length }})</span> -->
            </template>
            <TaskList />
          </TabPane>
        </Tabs>
      </template>
    </Popover>

    <audio ref="audioRef" :src="msgWechat"></audio>

    <MessagePreviewModal
      @register="registerMsgPreviewModal"
      @load-complete="getMessageTotal"
      @delete-message="getMessageTotal"
    />
  </div>
</template>
<script lang="ts" setup>
  import { computed, ref, h, onMounted, onBeforeUnmount, nextTick } from 'vue';
  import { Popover, Tabs, Badge, Image } from 'ant-design-vue';
  import { BellOutlined } from '@ant-design/icons-vue';
  import TaskList from './TaskList.vue';
  import { useDesign } from '@/hooks/web/useDesign';
  import { Button } from '@/components/Button';
  import { useIdentityStoreWithOut } from '@/store/modules/identity';

  import msgWechat from '@/assets/audios/msg_wechat.mp3';
  import infoImage from '@/assets/images/info_2x.png';

  import { columns } from './message.data';

  import { useI18n } from '@/hooks/web/useI18n';
  import { AdList, useAdList } from '@/components/AdList';
  import { useModal } from '@/components/AdVxeModal';
  import { useMessage } from '@/hooks/web/useMessage';
  import { formatToDate } from '@/utils/dateUtil';

  import { getUnreadMessages } from '@/api/message';

  // import { getMessageTypeEnumSchema } from '@/enums/messageTypeEnum';
  // import { getMessageLevelEnumSchema } from '@/enums/messageLevelEnum';

  import MessagePreviewModal from '@/views/system/msg/message/MessagePreviewModal.vue';

  const TabPane = Tabs.TabPane;
  const ImageBox = Image;
  const { prefixCls } = useDesign('header-notify');
  const { t } = useI18n();
  const { notification } = useMessage();

  const useIdentityStore = useIdentityStoreWithOut();
  const signalrHub = useIdentityStore.getSignalRHub;

  const audioRef = ref(); //音频标签对象
  const activeTab = ref(1); //活跃标签

  const messageTotal = ref<string | bigint>('0'); //消息数据

  // const messageTypeEnumSchema = getMessageTypeEnumSchema();
  // const messageLevelEnumSchema = getMessageLevelEnumSchema();

  const [registerMsgList, { reload: reloadMsgList }] = useAdList({
    // 表格数据接口请求对象
    api: getUnreadMessages,
    // 表单列信息 BasicColumn[]
    columns: columns,
    // 列表设置项
    listSetting: false,
    // 是否显示表格边框
    bordered: false,
    size: 'small',
    searchForm: false,
    compactHeight: true,
    maxHeight: 455,
    pagination: {
      pageSize: 5,
      defaultPageSize: 2,
      pageSizeOptions: ['5', '10', '15'],
      showQuickJumper: false,
      hideOnSinglePage: true,
    },
  });

  /** 处理查看消息详情 */
  function handleMsgFetchSuccess({ total }) {
    messageTotal.value = total;
  }

  const [registerMsgPreviewModal, msgPreviewModalMethods] = useModal();
  /** 处理查看消息详情 */
  async function handleMsgPreview(record: any) {
    msgPreviewModalMethods.openModal(true, {
      record: record,
      request: true,
    });
  }

  /** 下拉列表显示隐藏 */
  async function handlePopoverVisibleChange(visible: boolean) {
    // console.log(visible);
    if (visible) {
      nextTick(() => {
        setTimeout(async () => {
          await reloadMsgList();
        }, 30);
      });
    }
  }
  /** 下拉列表单击 */
  async function getMessageTotal() {
    nextTick(() => {
      setTimeout(async () => {
        const data = await getUnreadMessages({
          PageCondition: { PageIndex: 1, PageSize: 1, SortConditions: [] },
          FilterGroup: { Rules: [], Operate: 1, Groups: [], Level: 1 },
        });
        if (data) {
          messageTotal.value = data.Total;
        }
      }, 1000);
    });
  }

  // 组件挂载完成后执行的函数
  onMounted(async () => {
    await getMessageTotal();
    startListenMessage();
  });
  // 组件卸载前执行的函数
  onBeforeUnmount(() => {
    stopListenMessage();
  });

  /** 启动监听消息 */
  function startListenMessage() {
    //#region 查询消息
    signalrHub?.on('MSG_QUERY', async (msg: any) => {
      // console.log('MSG_QUERY', msg);
      audioRef.value.play();
      notification.info({
        key: `MSG_QUERY_${String(msg.Id)}`,
        icon: msg.Icon
          ? () =>
              h('img', {
                alt: 'icon',
                src: msg.Icon,
                width: 30,
              })
          : undefined,
        message: msg.Title,
        description: msg.Content,
        duration: 0,
        btn: () =>
          h(
            Button,
            {
              type: 'primary',
              size: 'small',
              onClick: () => {
                msgPreviewModalMethods.openModal(true, {
                  record: msg,
                  request: false,
                });
                notification.close(`MSG_QUERY_${String(msg.Id)}`);
              },
            },
            () => t('common.detailText'),
          ),
      });
      messageTotal.value = String(Number(messageTotal.value || '0') + 1);
    });
    signalrHub?.on('MSG_QUERY_DELETE', async (msg: any) => {
      // console.log('MSG_QUERY_DELETE', msg);
      notification.close(`MSG_QUERY_${String(msg.Id)}`);
      await getMessageTotal();
    });
    signalrHub?.on('MSG_QUERY_READ', async (msg: any) => {
      // console.log('MSG_QUERY_READ', msg);
      notification.close(`MSG_QUERY_${String(msg.Id)}`);
      await getMessageTotal();
    });
    signalrHub?.on('MSG_QUERY_UNREAD', async () => {
      // console.log('MSG_QUERY_UNREAD', msg);
      await getMessageTotal();
    });
    //#endregion
    //#region 模板消息
    signalrHub?.on('MSG_NOTICE', async (msg: any) => {
      // console.log('MSG_NOTICE', msg);
      audioRef.value.play();
      notification.info({
        key: `MSG_NOTICE_${String(msg.Id)}`,
        icon: msg.Icon
          ? () =>
              h('img', {
                alt: 'icon',
                src: msg.Icon,
                width: 30,
              })
          : undefined,
        message: msg.Title,
        description: msg.Content,
        duration: 0,
        btn: () =>
          h(
            Button,
            {
              type: 'primary',
              size: 'small',
              onClick: () => {
                msgPreviewModalMethods.openModal(true, {
                  record: msg,
                  request: false,
                });
                notification.close(`MSG_NOTICE_${String(msg.Id)}`);
              },
            },
            () => t('common.detailText'),
          ),
      });
      messageTotal.value = String(Number(messageTotal.value || '0') + 1);
    });
    signalrHub?.on('MSG_NOTICE_DELETE', async (msg: any) => {
      // console.log('MSG_NOTICE_DELETE', msg);
      notification.close(`MSG_NOTICE_${String(msg.Id)}`);
      await getMessageTotal();
    });
    signalrHub?.on('MSG_NOTICE_READ', async (msg: any) => {
      // console.log('MSG_NOTICE_READ', msg);
      notification.close(`MSG_NOTICE_${String(msg.Id)}`);
      await getMessageTotal();
    });
    signalrHub?.on('MSG_NOTICE_UNREAD', async () => {
      // console.log('MSG_NOTICE_UNREAD', msg);
      await getMessageTotal();
    });
    //#endregion
  }
  /** 停止监听消息 */
  function stopListenMessage() {
    //#region 查询消息
    signalrHub?.off('MSG_QUERY');
    signalrHub?.off('MSG_QUERY_DELETE');
    signalrHub?.off('MSG_QUERY_READ');
    signalrHub?.off('MSG_QUERY_UNREAD');
    //#endregion
    //#region 模板消息
    signalrHub?.off('MSG_NOTICE');
    signalrHub?.off('MSG_NOTICE_DELETE');
    signalrHub?.off('MSG_NOTICE_READ');
    signalrHub?.off('MSG_NOTICE_UNREAD');
    //#endregion
  }

  const getCount = computed(() => {
    let count = 0;
    const total = messageTotal.value;
    if (total) {
      count += Number(total);
    }
    return count;
  });
  const noticeAnimation = computed(() => {
    return getCount.value > 0;
  });
</script>
<style lang="less">
  @prefix-cls: ~'@{namespace}-header-notify';

  .@{prefix-cls} {
    padding-bottom: 1px;

    &__overlay {
      min-width: 360px;
      max-width: 400px;
    }

    .ant-tabs-content {
      width: 300px;
    }

    .ant-badge {
      display: flex;
      align-items: center;
      font-size: 18px;

      .ant-badge-multiple-words {
        padding: 0 4px;
      }

      svg {
        width: 0.9em;
      }
    }
  }

  @keyframes teetertotter-animation {
    0%,
    100%,
    20%,
    50%,
    80% {
      /* 设置只在Z轴上移动 */
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0);

      /* 贝塞尔曲线 ： X1 Y1 X2 Y2 */
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
      transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    }

    40%,
    43% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: translate3d(0, -30px, 0);
      transform: translate3d(0, -15px, 0);
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transition-timing-function: cubic-bezier(0.755, 0.5, 0.855, 0.06);
      transition-timing-function: cubic-bezier(0.755, 0.5, 0.855, 0.06);
    }

    70% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: translate3d(0, -15px, 0);
      transform: translate3d(0, -8px, 0);
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transition-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
      transition-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    }

    90% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: translate3d(0, -4px, 0);
      transform: translate3d(0, -4px, 0);
    }
  }

  @keyframes swing-animation {
    0%,
    65% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: rotate(0deg);
      transform: rotate(0deg);
    }

    70% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: rotate(8deg);
      transform: rotate(8deg);
    }

    75% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: rotate(-8deg);
      transform: rotate(-8deg);
    }

    80% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: rotate(8deg);
      transform: rotate(8deg);
    }

    85% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: rotate(-8deg);
      transform: rotate(-8deg);
    }

    90% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: rotate(8deg);
      transform: rotate(8deg);
    }

    95% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: rotate(-8deg);
      transform: rotate(-8deg);
    }

    100% {
      /* stylelint-disable-next-line property-no-vendor-prefix */
      -webkit-transform: rotate(0deg);
      transform: rotate(0deg);
    }
  }

  .notice-icon-animation {
    /* stylelint-disable-next-line property-no-vendor-prefix */
    -webkit-animation: teetertotter-animation 1s ease-in-out infinite;
    // animation: teetertotter-animation 1s ease-in-out infinite; //上下晃动
    // animation: swing-animation 1s ease-in-out infinite; //摆动动画
    animation: teetertotter-animation 1s ease-in-out infinite;
  }
</style>
